import { ref } from 'vue'

export default class DomUtil {
    /**
     * 获取触摸对象
     */
    static useTouch() {
        function getDirection(x: any, y: any) {
            if (x > y) {
                return 'horizontal'
            }
            if (y > x) {
                return 'vertical'
            }
            return ''
        }
        const startTime = ref(0)
        const offsetTime = ref(0)
        const startX = ref(0)
        const startY = ref(0)
        const deltaX = ref(0)
        const deltaY = ref(0)
        const offsetX = ref(0)
        const offsetY = ref(0)
        const direction = ref('')
        const isVertical = () => direction.value === 'vertical'
        const isHorizontal = () => direction.value === 'horizontal'
        const reset = () => {
            deltaX.value = 0
            deltaY.value = 0
            offsetX.value = 0
            offsetY.value = 0
            direction.value = ''
        }

        const end = (event?: any) => {
            offsetTime.value = new Date().getTime() - startTime.value
        }

        const start = (event: any) => {
            const e = event
            reset()
            startX.value = e.clientX !== undefined ? e.clientX : e.touches[0].clientX
            startY.value = e.clientY !== undefined ? e.clientY : e.touches[0].clientY
            startTime.value = new Date().getTime()
        }
        const move = (event: any) => {
            const e = event
            const touch =
                e.clientX !== undefined
                    ? {
                          clientX: e.clientX,
                          clientY: e.clientY
                      }
                    : e.touches[0]
            // safari back will set clientX to negative number
            deltaX.value = (touch.clientX < 0 ? 0 : touch.clientX) - startX.value
            deltaY.value = touch.clientY - startY.value
            offsetX.value = Math.abs(deltaX.value)
            offsetY.value = Math.abs(deltaY.value)
            // lock direction when distance is greater than a certain value
            const LOCK_DIRECTION_DISTANCE = 10
            if (
                !direction.value ||
                (offsetX.value < LOCK_DIRECTION_DISTANCE && offsetY.value < LOCK_DIRECTION_DISTANCE)
            ) {
                direction.value = getDirection(offsetX.value, offsetY.value)
            }
        }
        return {
            end,
            move,
            start,
            reset,
            startX,
            startY,
            deltaX,
            deltaY,
            offsetX,
            offsetY,
            direction,
            isVertical,
            isHorizontal,
            offsetTime
        }
    }

    /**
     *
     * @param ctx getCurrentInstance获取对象
     * @param idOrClass id或者class名称，id时返回一个对象，class为对象数组
     * @returns
     */
    static getNode(ctx: any, id: string, isCanvas: boolean = false): Promise<any> {
        return new Promise((resT) => {
            if (ctx === null) {
                resT(null)
                return
            }
            const getRes = (_node: any) => {
                // #ifdef H5
                if (isCanvas) {
                    _node = _node.querySelector('canvas')
                }
                const rect = _node.getBoundingClientRect()
                rect.node = _node
                resT(rect)
                // #endif

                // #ifdef MP-WEIXIN
                resT(_node)
                // #endif
            }

            // #ifdef MP-WEIXIN
            wx.createSelectorQuery()
                .in(ctx)
                .select(id)
                .fields({ node: true, size: true })
                .exec((res: any) => {
                    getRes(res[0])
                })
            // #endif

            // #ifdef H5
            getRes(document.querySelector(id))
            // #endif
        })
    }

    static _requestAnimationFrame(canvas: any) {
        // #ifdef H5
        return requestAnimationFrame
        // #endif
        // #ifdef MP-WEIXIN
        return canvas.requestAnimationFrame
        // #endif
    }
}
